import { getCacheSync, removeSpecificCaches, setCache } from '@/utils/cacheHelper'
import { debounce } from 'lodash'

/**
 * 缓存类型
 */
export enum CacheTypes {
  ApplianceList = 'APPLIANCE_LIST',
  AllPrograms = 'ALL_PROGRAMS',
}
// 所有缓存类型的值
const CacheTypeValues = Object.values(CacheTypes)

type UseCacheOptions<T> = {
  type: CacheTypes
  haId?: string
  watchDeep?: boolean
  watchImmediate?: boolean
  watchTrigger: () => T
  onCacheLoad: (data: T | '', haId?: string) => void
  checkIgnoreCache?: (data: T) => boolean // 是否需要设置缓存
  setCacheTransformer?: (data: T) => any // 设置缓存时的转换方法
}
type UseCacheReturned = {
  stopWatch: () => void
}
export function useCache<T>(options: UseCacheOptions<T>): Promise<UseCacheReturned> {
  const { type, haId, checkIgnoreCache, setCacheTransformer } = options

  // 获取缓存
  const cacheData = getApplianceCache({ type, haId })
  console.log('[CacheHelper] Get cache data: ', cacheData, `haId: ${haId}`)
  options.onCacheLoad(cacheData as T | '', haId)

  return new Promise((resolve) => {
    nextTick(() => {
      // 监听数据变化 设置缓存
      const stopWatch = watch(
        options.watchTrigger,
        debounce((data: T) => {
          // 是否需要设置缓存
          if (typeof checkIgnoreCache === 'function' && checkIgnoreCache(data)) return
          // 转换方法
          if (typeof setCacheTransformer === 'function') {
            data = setCacheTransformer(data)
            console.log('[CacheHelper] Cache data transformed to: ', data, `haId: ${haId}`)
          }
          console.log('[CacheHelper] Set cache data: ', data, `haId: ${haId}`)
          setApplianceCache({ type, data, haId })
        }, 300),
        { deep: options.watchDeep, immediate: options.watchImmediate }
      )

      return resolve({
        stopWatch,
      })
    })
  })
}

/**
 * 设置家电缓存数据
 */
export type SetOptions<T> = {
  type: CacheTypes
  haId?: string // 不传入则设置全局
  data: T
}
export function setApplianceCache<T>(options: SetOptions<T>): Promise<void> {
  const key = getApplianceCacheKey(options.type, options.haId)
  return setCache(key, options.data)
}

/**
 *  获取家电缓存数据
 */
export type GetOptions = {
  type: CacheTypes
  haId?: string
}
export function getApplianceCache<T>(options: GetOptions): T | undefined {
  const key = getApplianceCacheKey(options.type, options.haId)
  return getCacheSync<T>(key)
}

/**
 * 清空家电缓存Key
 */
export async function clearApplianceCache(haId?: string): Promise<void[]> {
  // 清空当前家电的缓存Key
  if (haId) {
    return removeSpecificCaches((key) => isApplianceCache(key, haId))
  }
  // 清空所有缓存Key
  return removeSpecificCaches((key: string) => isCacheType(key))
}

/**
 * ======= 工具方法 (Helper内部使用方法) =======
 */

/**
 * 获取家电缓存Key
 */
function getApplianceCacheKey(cacheType: CacheTypes, haId?: string) {
  return haId ? `${haId}-${cacheType}` : cacheType
}

/**
 * 判断缓存的Key 是否为家电相关的缓存类型
 * (不区分haId)
 */
function isCacheType(key: string) {
  return CacheTypeValues.some((cacheType) => key.endsWith(cacheType))
}

/**
 * 判断缓存的Key 是否为当前家电的缓存
 * (不区分缓存Key, 用于清空所有当前haId开头的缓存)
 */
function isApplianceCache(key: string, haId: string) {
  return key.startsWith(haId)
}
